
//
// 120205 - AH - (Bien) Created.
// 120321 - AH - Removed @Override for interface method (1.5 compatible).
//

package org.soekrat.gui.swing.motor.passingstrategy;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.StringTokenizer;

import javax.swing.JLabel;
import javax.swing.JPanel;

import org.soekrat.engine.Soekrat2Engine;
import org.soekrat.engine.motor.Motor;
import org.soekrat.engine.motor.passingstrategies.PassingStrategy;
import org.soekrat.engine.motor.passingstrategies.SequenceBasedPassingStrategy;
import org.soekrat.engine.motor.passingstrategies.WheelPassingStrategy;
import org.soekrat.engine.wheel.ontology.ForestOntology;
import org.soekrat.engine.wheel.ontology.MineOntology;
import org.soekrat.engine.wheel.ontology.NetworkOntology;
import org.soekrat.engine.wheel.ontology.ProductTableOntology;
import org.soekrat.gui.swing.motor.wheelpassingstrategy.LookaheadTextField;
import org.soekrat.gui.swing.motor.wheelpassingstrategy.StringArrayLookAhead;

/**
 * <p>
 *   Panel for defining a sequence of ontologies.
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC) 
 */
@SuppressWarnings("serial")
public final class OntologySequenceDefiningPanel extends JPanel
{
  private final Motor m_motor;
  
  private SequenceReceiver m_receiver=null;
  
  private final LookaheadTextField m_ltf=new LookaheadTextField(15);
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param se {@link Soekrat2Engine} interfaced.
   */
  public OntologySequenceDefiningPanel(Soekrat2Engine se)
  {
    if (se==null)
    {
      throw new NullPointerException("se");
    }
    
    m_motor=se.getMotor();
    
    setLayout(new BorderLayout());
    
    // TODO, REPLACE with suite logic
    StringArrayLookAhead dta=new StringArrayLookAhead
    (
      new String[]{ "Mine", "Network", "Forest", "Product Table" }
    );
    
    m_ltf.setLookAhead(dta);
    
    m_ltf.addActionListener
    (
      new ActionListener() 
      {
        public void actionPerformed(ActionEvent e) 
        {
          String name=m_ltf.getText();
          StringBuilder sb=new StringBuilder();
          
          String txt=m_receiver.getSequence();
          
          if (txt.length()>0)
          {
            sb.append(", ");
          }
          sb.append(name);
          
          m_ltf.setText("");
          m_receiver.sequence(txt+sb.toString());
          
          set();
        }
      }
    );
        
    JPanel center=new JPanel(new FlowLayout(FlowLayout.LEFT));
    
    add(center, BorderLayout.CENTER);
    
    JPanel south=new JPanel(new FlowLayout(FlowLayout.LEFT));
    south.add(new JLabel("Ontology: "));
    south.add(m_ltf);
    add(south, BorderLayout.SOUTH);
    
    init();
  }
  
  /**
   * <p>
   *   Sets objects to receive sequence.
   * </p>
   * @param sr Receiver or {@code null} if to clear.
   */
  public void setSequenceReceiver(SequenceReceiver sr){ m_receiver=sr; }
  
  @Override
  public void setEnabled(boolean v){ m_ltf.setEnabled(v); }
  
  void init()
  {   
    m_ltf.setText("");
     
    PassingStrategy ps=m_motor.getPassingStrategy();
    
    if (ps==null)
    {
      ps=new WheelPassingStrategy();
      m_motor.setPassingStrategy(ps);
    }
    
    if (ps instanceof WheelPassingStrategy)
    {      
      SequenceBasedPassingStrategy sbps=(SequenceBasedPassingStrategy)ps;
      
      String[] names=sbps.getSeguence();
      
      int n=names.length;
      StringBuilder sb=new StringBuilder();
      for (int i=0; i<n; i++)
      {
        if (i>0) sb.append(", ");
        String name=names[i];
        String uname=getOntologyClassForCname(name);
        sb.append(uname==null ? name : uname);
      }
      
      if (m_receiver!=null) m_receiver.sequence(sb.toString());
    }
  }
  
  void set()
  {
    WheelPassingStrategy wps=new WheelPassingStrategy();
    
    List<String> seq=new ArrayList<String>();
    
    String txt=(m_receiver==null) ? "" : m_receiver.getSequence();   
    
    StringTokenizer st=new StringTokenizer(txt, ",");
    
    while (st.hasMoreTokens())
    {
      String uname=st.nextToken();
      
      String cname=getOntologyClassNameForUname(uname);
      if (cname!=null)
      {
        seq.add(cname);
      }
    }
    wps.setSequence(seq);
    
    if (m_receiver!=null) m_receiver.sequence("");
    
    m_motor.setPassingStrategy(wps);
    
    init();
  }
  
  //
  // Stuff the Suite will take over.
  // 
  
  private static String getOntologyClassNameForUname(String uname)
  {
    uname=(uname==null) ? "" : uname.trim();
    uname=uname.toLowerCase();
    Class<?> clazz=c_ontologiesByUname.get(uname);
    return clazz==null ? null : clazz.getName();
  }
  
  private static String getOntologyClassForCname(String cname)
  {
    cname=(cname==null) ? "" : cname.trim();
    return c_ontologiesByCname.get(cname);
  }
  
  private static final Hashtable<String, Class<?>> c_ontologiesByUname=
    new Hashtable<String, Class<?>>();
  
  private static final Hashtable<String, String> c_ontologiesByCname=
    new Hashtable<String, String>();
  
  private static void registerOntology(String uname, Class<?> clazz)
  {
    c_ontologiesByUname.put(uname, clazz);
    c_ontologiesByCname.put(clazz.getName(), uname);
  }
  
  static
  {
    registerOntology("mine", MineOntology.class);
    registerOntology("network", NetworkOntology.class);
    registerOntology("forest", ForestOntology.class);
    registerOntology("product table", ProductTableOntology.class);
  }
  
}
